import argparse
import shutil
import sys

from flask import Flask, request, send_from_directory, render_template, url_for, Blueprint
import logging
import os
from urllib.parse import urlparse
from flask_cors import CORS, cross_origin

# 获取日志实例
logger = logging.getLogger(__name__)
# 设置日志级别
logger.setLevel(logging.INFO)
# 创建一个handler，用于写入日志文件
fh = logging.FileHandler('main.log')
# 创建一个handler，用于输出到控制台
ch = logging.StreamHandler()
# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# 给logger添加handler
logger.addHandler(fh)
logger.addHandler(ch)


trans_blueprint_prefix='/trans'
app = Flask(__name__, static_folder='static', static_url_path='{0}/static'.format(trans_blueprint_prefix))
bp = Blueprint('trans_blueprint', __name__, url_prefix=trans_blueprint_prefix)
CORS(app)  #允许所有路由上的所有域的CORS
port = 5000

uploadedDir = 'uploaded'


@bp.route('/hello', methods=['GET', 'POST'])
def hello_world():
    if request.method == 'GET':
        return {'message': 'hello'}
    elif request.method == 'POST':
        # 获取请求中的参数
        data = request.get_json()
        return data


@bp.route('/upload/', methods=['GET', 'POST'], defaults={'xxx': ''})
@bp.route('/upload/<path:xxx>', methods=['GET', 'POST'])
def upload(xxx):
    targetHost = request.headers.get('Host')
    targetPort = request.headers.get('Port', port)
    targetHost = targetHost.rsplit(':', maxsplit=1)[0] if targetHost.endswith(':{0}'.format(targetPort)) else targetHost

    foo = '{0}/{1}'.format(uploadedDir, xxx)
    api = {
        'upload': 'http://{0}:{1}/{2}/upload/{3}'.format(targetHost, targetPort, trans_blueprint_prefix, xxx)
    }

    if request.method == 'POST':

        file = request.files['file']
        if foo.endswith('/'):
            os.makedirs(foo, exist_ok=True)
            file.save('{0}/{1}'.format(foo, file.filename))
        else:
            os.makedirs(os.path.dirname(foo), exist_ok=True)
            file.save(foo)
        return {'message': '文件上传成功'}

    if request.method == 'GET':
        return render_template('upload.html', api=api)


@bp.route('/delete/', methods=['GET'], defaults={'xxx': ''})
@bp.route('/delete/<path:xxx>', methods=['GET'])
def delete(xxx):
    targetHost = request.headers.get('Host')
    targetPort = request.headers.get('Port', port)
    targetHost = targetHost.rsplit(':', maxsplit=1)[0] if targetHost.endswith(':{0}'.format(targetPort)) else targetHost

    foo = '{0}/{1}'.format(uploadedDir, xxx)

    if xxx == '':
        return '无法删除根目录'
    if os.path.isdir(foo):
        subpaths = os.listdir(foo)
        if len(subpaths) > 0:
            return '还存在文件或文件夹'
    os.remove(foo)
    return '删除成功'


# 静态资源下载
@bp.route('/{0}/'.format(uploadedDir), methods=['GET', 'DELETE'], defaults={'xxx': ''})
@bp.route('/{0}/<path:xxx>'.format(uploadedDir), methods=['GET', 'DELETE'])
def uploaded(xxx):
    targetHost = request.headers.get('Host')
    targetPort = request.headers.get('Port', port)
    targetHost = targetHost.rsplit(':', maxsplit=1)[0] if targetHost.endswith(':{0}'.format(targetPort)) else targetHost

    logger.info("targetHost: {0}".format(targetHost))
    logger.info("targetPort: {0}".format(targetPort))
    logger.info("request.headers:\n{0}".format(request.headers))

    foo = '{0}/{1}'.format(uploadedDir, xxx)

    if request.method == 'GET':

        if xxx == '' or os.path.isdir(foo):
            subpaths = os.listdir(foo)
            items = [
                {
                    'name': subpath,
                    'url': 'http://{0}:{1}/{2}/{3}/{4}'.format(targetHost, targetPort, trans_blueprint_prefix,foo, subpath)
                }
                for subpath in subpaths
            ]
            return render_template('uploaded.html', items=items)

        if os.path.isfile(foo):
            return send_from_directory(uploadedDir, xxx)

    if request.method == 'DELETE':
        if xxx == '':
            return '无法删除根目录'
        if os.path.isdir(foo):
            subpaths = os.listdir(foo)
            if len(subpaths) > 0:
                return '还存在文件或文件夹'
            #os.remove(foo)
            shutil.rmtree(foo)
            return '删除目录成功'
        if os.path.isfile(foo):
            os.remove(foo)
            return '删除文件成功'

app.register_blueprint(bp)

if __name__ == '__main__':
    app.run(
        host='0.0.0.0',
        port=port,
        debug=True
    )

    # socket=127.0.0.1:5000
    # socket=106.15.139.127:5000

    # app run host 一定要设置成允许外网访问，不然即便安全组开通了，telnet也是失败，接口也无法访问
    # curl http://${socket}/uploaded -X POST -F 'file=@/Users/zhaojinhui/Downloads/FEA8180805055E684EEBFE01A40BF60C.txt'
    # http://${socket}/.well-known/pki-validation/FEA8180805055E684EEBFE01A40BF60C.txt
    # curl http://${socket}/uploaded/zerossl/ -X POST -F 'file=@/Users/zhaojinhui/Downloads/106.15.139.127/default/ca_bundle.crt'
    # curl http://${socket}/uploaded/zerossl/ -X POST -F 'file=@/Users/zhaojinhui/Downloads/106.15.139.127/default/certificate.crt'
    # curl http://${socket}/uploaded/zerossl/ -X POST -F 'file=@/Users/zhaojinhui/Downloads/106.15.139.127/default/private.key'
